﻿using System;
using UIShell.OSGi;

namespace Pasys.PresentationCore.WinForms
{
    internal class StatusMonitor
    {

        public StatusMonitor(string commandName, Action<object, bool> changeEnable, Action<object, bool> changeVisible)
        {
            if (string.IsNullOrEmpty(commandName))
            {
                throw new ArgumentException();
            }
            ChangeEnable = changeEnable;
            ChangeVisible = changeVisible;

            Subscribe(commandName);


        }

        //public CommandStatusMonitor(string commandName)
        //    : this(commandName, null, null)
        //{
        //}

        public Action<object, bool> ChangeEnable { get; set; }
        public Action<object, bool> ChangeVisible { get; set; }


        protected virtual void Subscribe(string commandName)
        {
        }

        protected void UIInvoke(Action action)
        {
            var layoutView = BundleRuntime.Instance.GetFirstOrDefaultService<IShellLayoutViewProxy>();
            layoutView.Invoke(action);
        }

        protected void OnCommandReceived(object sender, object e)
        {
            var contact = (CommandStatusContact)e;

            switch (contact.Status)
            {
                case CommandStatus.Enabled:
                    if (ChangeEnable != null)
                        ChangeEnable(sender, true);
                    break;
                case CommandStatus.Disabled:
                    if (ChangeEnable != null)
                        ChangeEnable(sender, false);
                    break;
                case CommandStatus.Hide:
                    if (ChangeVisible != null)
                    {
                        ChangeVisible(sender, false);
                    }
                    break;
                case CommandStatus.Visible:
                    if (ChangeVisible != null)
                    {
                        ChangeVisible(sender, true);
                    }
                    break;

                default:
                    break;
            }
        }
    }

    internal class CommandStatusMonitor : StatusMonitor
    {
        public CommandStatusMonitor(string commandName, Action<object, bool> changeEnable, Action<object, bool> changeVisible)
            : base(commandName, changeEnable, changeVisible)
        { }

        protected override void Subscribe(string commandName)
        {
            var commandService = BundleRuntime.Instance.GetFirstOrDefaultService<ICommandBusService>();
            if (commandService != null)
            {
                commandService.SubscribeCommandStatusEvent(commandName,
                                                           (sender, e) => UIInvoke(() => OnCommandReceived(sender, e)));
            }
        }
    }

    internal class CommandGroupStatusMonitor : StatusMonitor
    {
        public CommandGroupStatusMonitor(string commandName, Action<object, bool> changeEnable, Action<object, bool> changeVisible)
            : base(commandName, changeEnable, changeVisible)
        { }
        protected override void Subscribe(string commandName)
        {
            var commandService = BundleRuntime.Instance.GetFirstOrDefaultService<ICommandBusService>();
            if (commandService != null)
            {
                commandService.SubscribeCommandGroupStatusEvent(commandName,
                                                           (sender, e) => UIInvoke(() => OnCommandReceived(sender, e)));
            }
        }
    }

}